﻿namespace AmazonS3PublishPlugin
{
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Diagnostics.Contracts;
    using System.Text.RegularExpressions;
    using System.Xml;
    using System.Xml.Serialization;
    using Amazon.S3;
    using Amazon.S3.Model;
    using Amazon.S3.Transfer;
    using AmazonS3PublishPlugin.Properties;

    public class PublishData : INotifyPropertyChanged, IDataErrorInfo
    {
        private static readonly Regex FolderNameRegex = new Regex(@"^([^/]+/)*([^/]+)?$", RegexOptions.Compiled);

        private static readonly XmlSerializer _xmlSerializer = new XmlSerializer(typeof(PublishData));

        public PublishData()
        {
            MakePublic = true;
            UseHttps = true;
            UseJobOutputFolder = true;
            OpenInBrowser = true;
            FolderName = string.Empty;
        }

        public string AccessKeyId { get; set; }

        public string SecretAccessKey { get; set; }

        public bool SaveSecretAccessKey { get; set; }

        [XmlIgnore]
        public IEnumerable<S3Bucket> Buckets { get; internal set; }

        [XmlIgnore]
        public AuthenticateStatus AuthenticateStatus { get; set; }

        public string BucketName { get; set; }

        public string FolderName { get; set; }

        public bool IsCredentialSet
        {
            get { return !string.IsNullOrWhiteSpace(AccessKeyId) && !string.IsNullOrWhiteSpace(SecretAccessKey); }
        }

        public bool UseJobOutputFolder { get; set; }

        public bool UseReducedRedundancyStorage { get; set; }

        public bool MakePublic { get; set; }

        public bool UseHttps { get; set; }

        public bool OpenInBrowser { get; set; }

        public string Error
        {
            get { return null; }
        }

        public string this[string columnName]
        {
            get
            {
                string result = null;

                if (columnName == "FolderName")
                {
                    if (!FolderNameRegex.IsMatch(FolderName))
                    {
                        result = Resources.InvalidFolderName;
                    }
                }

                return result;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public static PublishData Load(XmlReader reader)
        {
            return (PublishData)_xmlSerializer.Deserialize(reader);
        }

        public void Save(XmlWriter writer)
        {
            _xmlSerializer.Serialize(writer, this);
        }

        internal AmazonS3Client CreateClient()
        {
            Contract.Requires(IsCredentialSet);

            var config = new AmazonS3Config()
                .WithCommunicationProtocol(UseHttps ? Protocol.HTTPS : Protocol.HTTP);
            return new AmazonS3Client(AccessKeyId, SecretAccessKey, config);
        }

        internal TransferUtility CreateTransferUtility()
        {
            Contract.Requires(IsCredentialSet);

            return new TransferUtility(AccessKeyId, SecretAccessKey);
        }
    }
}